﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Reflection;
using System.Collections.ObjectModel;
using ASPItalia.ModelVirtualCasting.Silverlight.Models;
using MVCSS = ASPItalia.ModelVirtualCasting.Silverlight.ModelVirtualCastingServices;
using System.Threading;
using System.Windows.Data;
using Microsoft.Practices.Composite.Presentation.Commands;

namespace ASPItalia.ModelVirtualCasting.Silverlight.ViewModels
{
  public class FilterData : INotifyPropertyChanged
  {
    public event PropertyChangedEventHandler PropertyChanged;

    private string fullName;
    public string FullName
    {
      get { return fullName; }
      set
      {
        fullName = value;
        this.OnPropertyChanged(MethodBase.GetCurrentMethod().Name.Remove(0, 4));
      }
    }
    private string firstName;
    public string FirstName
    {
      get { return firstName; }
      set
      {
        firstName = value;
        this.OnPropertyChanged(MethodBase.GetCurrentMethod().Name.Remove(0, 4));
      }
    }

    private string lastName;
    public string LastName
    {
      get { return lastName; }
      set
      {
        lastName = value;
        this.OnPropertyChanged(MethodBase.GetCurrentMethod().Name.Remove(0, 4));
      }
    }

    protected void OnPropertyChanged(string propertyName)
    {
      PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
      if (propertyChanged != null)
        propertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
  }

  public class MainViewModel : INotifyPropertyChanged
  {
    IDataModelsModel dataModel;
    public event PropertyChangedEventHandler PropertyChanged;

    public DelegateCommand<object> FilterCommand { get; set; }
    public DelegateCommand<object> ViewModelDetailsCommand { get; set; }
    public ButtonCommand<string> SendRequestFormCommand { get; set; }
    public ButtonCommand<string> PrintFormCommand { get; set; }

    //public MainViewModel() : this(new DataModelsFakeModel()) { }
    public MainViewModel() : this(new DataModelsServiceModel()) { }

    public MainViewModel(IDataModelsModel dataModel)
    {
      this.dataModel = dataModel;
      this.dataModel.AllModelsLoadCompleted += new EventHandler<AllModelsLoadedEventArgs>(dataModel_AllModelsLoadCompleted);
      this.dataModel.DataLoadingError += new EventHandler<DataLoadingErrorEventArgs>(dataModel_DataLoadingError);

      ThreadPool.QueueUserWorkItem(this.GetAllModels, null);

      this.FilterData = new FilterData();
      this.ModelsList.Filter += new FilterEventHandler(ModelsList_Filter);
      this.ModelsSelectedList.Filter += new FilterEventHandler(ModelsList_Filter);
      this.FilterCommand = new DelegateCommand<object>(Filtering);
      this.ViewModelDetailsCommand = new DelegateCommand<object>(ShowModelDetailsCommand);

      this.SendRequestFormCommand = new ButtonCommand<string>(OpenSendRequestFormCommand, CanOpenSendRequestForm);
      this.PrintFormCommand = new ButtonCommand<string>(OpenPrintFormCommand, CanOpenPrintForm);

      this.modelsSelectedList.Source = new ObservableCollection<MVCSS.Model>();
    }

    public void GetAllModels(object state)
    {
      Deployment.Current.Dispatcher.BeginInvoke(() =>
      {
        ModelListLoading = true;
      });

      dataModel.GetAllModels();
    }

    void dataModel_AllModelsLoadCompleted(object sender, AllModelsLoadedEventArgs e)
    {
      Deployment.Current.Dispatcher.BeginInvoke(() =>
      {
        modelsList.Source = e.Result;
        ModelListLoading = false;
        ModelListLoadingError = false;
      });
    }

    void dataModel_DataLoadingError(object sender, DataLoadingErrorEventArgs e)
    {
      ModelListLoading = false;
      ModelListLoadingError = true;
      MessageBoxResult messageResult = MessageBox.Show("Ricaricare i dait?", "Errore nel caricamento", MessageBoxButton.OKCancel);
      if (messageResult == MessageBoxResult.OK)
        ThreadPool.QueueUserWorkItem(this.GetAllModels, null);
    }

    public FilterData filterData;
    public FilterData FilterData
    {
      get { return filterData; }
      set
      {
        filterData = value;
        this.OnPropertyChanged(MethodBase.GetCurrentMethod().Name.Remove(0, 4));
      }
    }

    CollectionViewSource modelsList = new CollectionViewSource();
    public CollectionViewSource ModelsList
    {
      get { return modelsList; }
    }

    CollectionViewSource modelsSelectedList = new CollectionViewSource();
    public CollectionViewSource ModelsSelectedList
    {
      get { return modelsSelectedList; }
    }

    MVCSS.Model currentModel;
    public MVCSS.Model CurrentModel
    {
      get { return currentModel; }
      set
      {
        currentModel = value;
        this.OnPropertyChanged(MethodBase.GetCurrentMethod().Name.Remove(0, 4));
      }
    }

    private bool modelListLoading = false;
    public bool ModelListLoading
    {
      get { return modelListLoading; }
      set
      {
        modelListLoading = value;
        this.OnPropertyChanged(MethodBase.GetCurrentMethod().Name.Remove(0, 4));
      }
    }

    private bool modelListLoadingError = false;
    public bool ModelListLoadingError
    {
      get { return modelListLoadingError; }
      set
      {
        modelListLoadingError = value;
        this.OnPropertyChanged(MethodBase.GetCurrentMethod().Name.Remove(0, 4));
      }
    }

    private bool filterRightData = false;
    public bool FilterRightData
    {
      get { return filterRightData; }
      set
      {
        filterRightData = value;
        this.OnPropertyChanged(MethodBase.GetCurrentMethod().Name.Remove(0, 4));
      }
    }

    void ModelsList_Filter(object sender, FilterEventArgs e)
    {
      if (e.Item != null && this.FilterData != null)
      {
        MVCSS.Model item = e.Item as MVCSS.Model;
        if (!string.IsNullOrEmpty(filterData.FullName))
        {
          string[] fullNamePart = this.filterData.FullName.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

          if (fullNamePart.Length > 0 && !String.IsNullOrEmpty(fullNamePart[0]))
          {
            if (!item.FirstName.ToLower().StartsWith(fullNamePart[0].ToLower()))
              e.Accepted = false;
          }

          if (fullNamePart.Length > 1 && !String.IsNullOrEmpty(fullNamePart[1]))
          {
            if (!item.LastName.ToLower().StartsWith(fullNamePart[1]))
              e.Accepted = false;
          }
        }
      }
    }
    public void Filtering(object o)
    {
      if (FilterRightData)
      {
        this.ModelsSelectedList.View.Refresh();
      }
      else
      {
        ModelsList.View.Refresh();
      }
    }

    //dettagli
    public void ShowModelDetailsCommand(object o)
    {
      ChildWindow child = new ModelDetails(this);
      child.Show();
    }

    //richiesta informazioni
    public bool CanOpenSendRequestForm(string value)
    {
      return true;
    }
    public void OpenSendRequestFormCommand(string value)
    {
      ChildWindow child = new RequestModelDetails(this);
      child.Show();
    }

    //stampa
    public bool CanOpenPrintForm(string value)
    {
      return true;
    }
    public void OpenPrintFormCommand(string value)
    {
      ChildWindow child = new PrintModelDetails(this);
      child.Show();
    }

    protected void OnPropertyChanged(string propertyName)
    {
      PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
      if (propertyChanged != null)
        propertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
  }
}
